<template>
	<el-dialog v-model="dialogVisible" :title="`批量添加${parameter.title}`" destroy-on-close width="580px" draggable>
		<el-form class="drawer-multiColumn-form" label-width="100px">
			<el-form-item label="模板下载 :">
				<el-button type="primary" :icon="Download" @click="downloadTemp">点击下载</el-button>
			</el-form-item>
			<!-- 	 -->
			<el-form-item label="文件上传 :" v-if="dialogVisible">
				<el-upload
					class="upload"
					:drag="true"
					v-model:file-list="fileList"
					:limit="excelLimit"
					:multiple="true"
					:disabled="uploadDisabled"
					:show-file-list="true"
					:before-upload="beforeExcelUpload"
					:http-request="uploadExcel"
					:on-exceed="handleExceed"
					:on-remove="handleRemove"
					:on-success="excelUploadSuccess"
					:on-error="excelUploadError"
					accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
				>
					<el-icon class="el-icon--upload"><upload-filled /></el-icon>
					<div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
					<template #tip>
						<div class="el-upload__tip">
							<div>1、导入前请先下载对应的模板；</div>
							<div>2、按照模板填入相应的信息；</div>
							<div>3、导入时选择填写好的Excel文件；</div>
							<div class="flex flex-wrap" v-if="fileResult?.total || fileResult?.total === 0">
								<div>
									本次导入<span class="primary-color fwb">{{ fileResult?.total }}</span
									>总数，导入成功<span class="success-color fwb">{{ fileResult?.succ ?? fileResult?.success ?? 0 }}</span
									>条，导入失败<span class="danger-color fwb">{{ fileResult?.fail ?? 0 }}</span
									>条
								</div>
								<el-link type="success" v-if="fileResult?.fail > 0 || fileResult?.serviceId" @click="downloadFailFile"
									>下载导入失败的清单</el-link
								>
							</div>
							<div v-else>
								<span v-if="fileResult?.serviceId" class="danger-color">本次导入有失败的数据；</span>
								<!-- <span v-if="isUpFile" class="success-color">本次导入数据成功；</span> -->
								<el-link type="success" v-if="fileResult?.serviceId" @click="downloadFailFile">下载导入失败的清单</el-link>
							</div>
						</div>
					</template>
					<el-progress v-if="percentage !== 0" :percentage="percentage" />
				</el-upload>
			</el-form-item>
		</el-form>
	</el-dialog>
</template>

<script setup lang="ts" name="ImportExcel">
import { ref, watch } from 'vue';
import { useDownload } from '@/hooks/useDownload';
import { Download } from '@element-plus/icons-vue';
import { ElNotification } from 'element-plus';
import { downloadFile } from '@/api/modules/user';
import type { UploadUserFile, UploadProps } from 'element-plus';

export interface ExcelParameterProps {
	title: string; // 标题
	params?: any; // 导入和导出的参数
	tempApi: (params: any) => Promise<any>; // 下载模板的Api
	importApi: (params: any, params2?: any) => Promise<any>; // 批量导入的Api
	getTableList?: () => Promise<any>; // 获取表格数据的Api
	errorDownFile?: () => Promise<any>; // 下载导入失败的清单
}
const percentage = ref(0);
const changeTime = ref<any>();
const uploadDisabled = ref(false);
const fileList = ref<UploadUserFile[]>([]);
const fileResult = ref<any>({});
// 是否覆盖数据
const isCover = ref(false);
// 最大文件上传数
const excelLimit = ref(1);
// dialog状态
const dialogVisible = ref(false);
// 父组件传过来的参数
const parameter = ref<Partial<ExcelParameterProps>>({});

// 接收父组件参数
const acceptParams = (params?: any): void => {
	parameter.value = params;
	dialogVisible.value = true;
};

// Excel 导入模板下载
const downloadTemp = () => {
	console.log(parameter.value.tempApi);
	if (!parameter.value.tempApi) return;
	const param = parameter.value?.params ?? { fileName: '模版' };
	useDownload(parameter.value.tempApi, `${parameter.value.title}模板`, { ...param }, true);
};

const downloadFailFile = () => {
	// 判断是否存在 errorDownFile 方法
	const errorDownFile = parameter.value.errorDownFile;
	useDownload(errorDownFile ?? downloadFile, '失败清单', { keyId: fileResult.value?.serviceId ?? fileResult.value?.keyId });
};

// 文件上传
const uploadExcel = async (param: any) => {
	try {
		const excelFormData = new FormData();
		excelFormData.append('file', param.file);
		excelFormData.append('isCover', isCover.value as unknown as Blob);
		const params = parameter.value?.params;
		if (params) {
			for (const key in params) {
				excelFormData.append(key, params[key]);
			}
		}
		changePercentage();
		uploadDisabled.value = true;
		// console.log('excelFormData', excelFormData);
		const { data } = await parameter.value.importApi!(excelFormData);
		fileResult.value = data;
		console.log(fileResult.value);
		parameter.value.getTableList && parameter.value.getTableList();
		clearInterval(changeTime.value);
		percentage.value = 100;
		uploadDisabled.value = false;
		const clearTime = setTimeout(() => {
			percentage.value = 0;
			clearTimeout(clearTime);
		}, 1500);
	} catch (error) {
		excelUploadError();
		clearInterval(changeTime.value);
		percentage.value = 0;
		fileList.value = [];
		uploadDisabled.value = false;
	}
	// dialogVisible.value = false;
};

const handleRemove: UploadProps['onRemove'] = () => {
	fileResult.value = {};
};

const changePercentage = () => {
	changeTime.value = setInterval(() => {
		percentage.value += 1;
		if (percentage.value === 100) {
			clearInterval(changeTime.value);
		}
	}, 1000);
};

/**
 * @description 文件上传之前判断
 * @param file 上传的文件
 * */
const beforeExcelUpload = (file: any) => {
	const isExcel =
		file.type === 'application/vnd.ms-excel' || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
	const fileSize = file.size / 1024 / 1024 < 5;
	if (!isExcel)
		ElNotification({
			title: '温馨提示',
			message: '上传文件只能是 xls / xlsx 格式！',
			type: 'warning'
		});
	if (!fileSize)
		ElNotification({
			title: '温馨提示',
			message: '上传文件大小不能超过 5MB！',
			type: 'warning'
		});
	return isExcel && fileSize;
};

// 文件数超出提示
const handleExceed = (): void => {
	ElNotification({
		title: '温馨提示',
		message: '最多只能上传一个文件！',
		type: 'warning'
	});
};

// 上传错误提示
const excelUploadError = (): void => {
	ElNotification({
		title: '温馨提示',
		message: `批量添加${parameter.value.title}失败，请您重新上传！`,
		type: 'error'
	});
};

// 上传成功提示
const excelUploadSuccess = (): void => {
	fileResult.value?.success > 0 &&
		ElNotification({
			title: '温馨提示',
			message: `批量添加${parameter.value.title}成功！`,
			type: 'success'
		});
};

watch(
	() => dialogVisible.value,
	val => {
		if (!val) {
			fileResult.value = {};
			fileList.value = [];
		}
	}
);

defineExpose({
	acceptParams,
	dialogVisible
});
</script>
<style lang="scss" scoped>
.upload {
	width: 80%;
}
</style>
